package com.atguigu.gmall.controller;

import com.atguigu.gmall.common.result.Result;
import com.atguigu.gmall.list.client.ListFeignClient;
import com.atguigu.gmall.model.list.SearchParam;
import com.atguigu.gmall.model.list.SearchResponseVo;
import com.atguigu.gmall.model.product.BaseAttrInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author: 封捷
 * @create-date: 2022/9/2 9:22
 */
@Controller
public class ListController {

    @Autowired
    private ListFeignClient listFeignClient;

    @RequestMapping("/list.html")
    public String doSearch(SearchParam searchParam, Model model) throws Throwable {

        // 1、调用远程接口获取查询结果
        Result<SearchResponseVo> searchResponseVoResult =
                listFeignClient.search(searchParam);

        SearchResponseVo searchResponseVo = searchResponseVoResult.getData();

        // 2、将查询结果中各个属性数据存入模型（也就是存入请求域）
        model.addAttribute("trademarkList", searchResponseVo.getTrademarkList());
        model.addAttribute("attrsList", searchResponseVo.getAttrsList());
        model.addAttribute("goodsList", searchResponseVo.getGoodsList());
        model.addAttribute("pageNo", searchResponseVo.getPageNo());
        model.addAttribute("totalPages", searchResponseVo.getTotalPages());

        // 3、拼接要附加到 URL 地址后的参数
        String urlParam = makeUrlParam(searchParam);

        // 4、拼接页面显示需要使用的品牌数据
        String trademarkDisplay = makeTrademarkDisplay(searchParam);

        // 5、拼接页面显示需要使用的平台属性数据
        // [1]创建存放平台属性数据的 List 集合
        // 集合中每一个 Map<String, String>，都对应的页面上显示的一条平台属性数据
        // Map<String, String> 中应该包含下面三个数据：
        // attrId:2
        // attrName:屏幕尺寸
        // attrValue:6.75-6.84英寸
        List<Map<String, String>> propList = makeProps(searchParam);

        // 6、拼接页面显示需要的排序数据
        Map<String, String> orderMap = makeOrderMap(searchParam);

        // 7、将上述数据存入模型（也就是存入请求域）
        model.addAttribute("urlParam", urlParam);
        model.addAttribute("trademarkParam", trademarkDisplay);
        model.addAttribute("propsParamList", propList);
        model.addAttribute("orderMap", orderMap);

        return "list/index";
    }

    /**
     * 生成排序规则 Map
     * @param searchParam
     * @return
     */
    private Map<String, String> makeOrderMap(SearchParam searchParam) {

        // 创建封装返回结果的 Map 集合
        Map<String, String> resultMap = new HashMap<>();

        // Order字符串的格式：2:desc
        String order = searchParam.getOrder();

        // 排除 order 不存在的情况
        if(StringUtils.isEmpty(order)) {
            resultMap.put("type", "1");
            resultMap.put("sort", "asc");
            return resultMap;
        }

        // 排除 order 格式不正确的情况
        String[] split = order.split(":");
        if (split == null || split.length != 2) {
            resultMap.put("type", "1");
            resultMap.put("sort", "asc");
            return resultMap;
        }

        // 解析 order 字符串
        String type = split[0];
        String sort = split[1];

        // 封装到 Map 中
        resultMap.put("type", type);
        resultMap.put("sort", sort);

        return resultMap;
    }

    /**
     * 用于拼接平台属性信息在页面上要显示的字符串集合
     * 字符串格式：平台属性名：平台属性值
     * @param searchParam
     * @return
     */
    private List<Map<String, String>> makeProps(SearchParam searchParam) {

        // 1、获取平台属性数据
        String[] props = searchParam.getProps();

        if (props != null && props.length > 0) {
            // 2、创建集合对象，用于保存解析和拼接的结果
            List<Map<String, String>> propList = new ArrayList<>();

            // 3、遍历 props 数组
            for (int i = 0; i < props.length; i++) {
                // 4、每一个 prop 数据都是一条平台属性数据，对应一个 Map
                String prop = props[i];

                // 5、拆分平台属性数据
                String[] split = prop.split(":");
                if (split != null && split.length == 3) {

                    // 平台属性 id
                    String attrId = split[0];

                    // 平台属性名
                    String attrName = split[2];

                    // 平台属性值
                    String attrValue = split[1];

                    // 封装到 Map 中
                    Map<String, String> propMap = new HashMap<>();

                    propMap.put("attrId", attrId);
                    propMap.put("attrName", attrName);
                    propMap.put("attrValue", attrValue);

                    // 将 Map 存入 List<Map<String, String>> propList
                    propList.add(propMap);
                }
            }

            return propList;
        }

        return null;
    }

    /**
     * 用于拼接品牌信息在页面上要显示的字符串
     * 字符串格式：品牌:品牌名称
     * @param searchParam
     * @return
     */
    private String makeTrademarkDisplay(SearchParam searchParam) {

        String trademark = searchParam.getTrademark();

        if(!StringUtils.isEmpty(trademark)) {
            String[] split = trademark.split(":");
            if (split != null && split.length == 2) {
                String trademarkName = split[1];
                String trademarkParam = "品牌：" + trademarkName;
                return trademarkParam;
            }
        }

        return null;
    }

    /**
     * SearchParam 实体类封装了前端传过来的所有请求参数，
     * 而这些参数在翻页的过程中又需要保持，
     * 所以需要拼接成一个能够放在 URL 地址后面的请求参数字符串
     * @param searchParam
     * @return
     */
    private String makeUrlParam(SearchParam searchParam) {

        StringBuilder paramBuilder = new StringBuilder();

        // 1、一级分类
        if (searchParam.getCategory1Id() != null) {
            paramBuilder.append("category1Id=").append(searchParam.getCategory1Id());
        }

        // 2、二级分类
        if (searchParam.getCategory2Id() != null) {
            paramBuilder.append("category2Id=").append(searchParam.getCategory2Id());
        }

        // 3、三级分类
        if (searchParam.getCategory3Id() != null) {
            paramBuilder.append("category3Id=").append(searchParam.getCategory3Id());
        }

        // 4、关键词
        if (!StringUtils.isEmpty(searchParam.getKeyword())) {
            paramBuilder.append("keyword=").append(searchParam.getKeyword());
        }
        // ※说明：上面四个参数，不可能同时出现两个或两个以上

        // 5、品牌
        // ※说明：附加 paramBuilder.length()>0 判断是因为如果前面没有拼入，
        // 说明用户没有到搜索结果页面，不可能点击品牌图标
        if (searchParam.getTrademark() != null && paramBuilder.length()>0) {
            paramBuilder.append("&trademark=").append(searchParam.getTrademark());
        }

        // 7、平台属性
        // [1]获取平台属性的字符串数组
        String[] props = searchParam.getProps();

        // [2]遍历数组执行拼接
        // ※说明：附加 paramBuilder.length()>0 判断是因为如果前面没有拼入，
        // 说明用户没有到搜索结果页面，不可能点击品牌图标
        if (paramBuilder.length()>0 && props != null) {
            for (int i = 0; i < props.length; i++) {
                String prop = props[i];
                paramBuilder.append("&props=").append(prop);
            }
        }

        return "list.html?" + paramBuilder.toString();
    }

}
